﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace AgentTest
{
    public delegate void DespoolNotificationDelegate(byte[] constructor, byte[] input, byte[] output);

    public delegate void BoundStateChangedHandler(ServiceEndpoint serviceEndpoint);

    public interface IBinder
    {
        IList<ServiceEndpoint> GetServers();
    }

    public class Broker
    {
//        string m_spoolDirectoryPath;

//        // Default rebind internal.  Note that DA doesn't use this default, but instead passes in a
//        // value to the constructor to be used.  So, this value is only for test utilities, and
//        // possibly future Vegas apps.
//        static readonly TimeSpan DEFAULT_FORCE_REBIND_INTERVAL = TimeSpan.FromHours(2);

//        // Default read timeout is "no timeout".
//        static readonly TimeSpan DEFAULT_READ_TIMEOUT = TimeSpan.FromMilliseconds(-1);

//        // How often we check our binding.
//        int BINDING_INTERVAL = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;

//        // How often we randomly pick another server.
//        TimeSpan m_forceRebindInterval;
//        ReaderWriterLock m_rebindLock = new ReaderWriterLock();
//        object m_vegasSessionMutex = new object(); // protects both m_vegasSession and m_currentBinding.  Don't hold this while calling outside this class.
//        VegasSession m_vegasSession = null;
//        ServiceEndpoint m_currentBinding = null;
//        Timer m_bindingTimer;
//        Timer m_rebindTimer;
//        TimeSpan m_readTimeout;
//        bool m_forceRebind = false;
//        IBinder m_binder;
//        bool m_bindInProgress = false;
//        object m_bindInProgressMutex = new object();

//        Dictionary<Guid, DespoolNotificationDelegate> m_callbacks = new Dictionary<Guid, DespoolNotificationDelegate>();
//        DeSpooler m_despooler;
//        Random m_random = new Random();

//        public const string VEGAS_CLIENT_CATEGORY =
//            "Vegas Client";
//        private const string VEGAS_CLIENT_CATEGORY_HELP =
//            "Counters for the Vegas Client library";

//        //         public const string VEGAS_CLIENT_SPOOL_TIME =
//        //             "Spool Write Time";
//        //         private const string VEGAS_CLIENT_SPOOL_TIME_HELP =
//        //             "The average time for Vegas to write data to disk once it has acquired a lock to the spool file.";

//        //         public const string VEGAS_CLIENT_MAX_SPOOL_TIME =
//        //             "Max Spool Write Time";
//        //         private const string VEGAS_CLIENT_MAX_SPOOL_TIME_HELP =
//        //             "Maximum time to write to spool since the last session was opened";

//        //         public const string VEGAS_CLIENT_SPOOL_BYTES_WRITTEN =
//        //             "Spool Bytes Written";
//        //         private const string VEGAS_CLIENT_SPOOL_BYTES_WRITTEN_HELP =
//        //             "Total number of bytes written to spool since the last session was opened";

//        //         public const string VEGAS_CLIENT_SPOOL_NUM_WRITES =
//        //             "Spool Num Writes";
//        //         private const string VEGAS_CLIENT_SPOOL_NUM_WRITES_HELP =
//        //             "Total number of writes (packets) written to spool since the last session was opened";

//        //         public const string VEGAS_CLIENT_DESPOOL_TIME =
//        //             "Despool Time";
//        //         private const string VEGAS_CLIENT_DESPOOL_TIME_HELP =
//        //             "Time to despool message, send to collector, and receive ack.";

//        //         public const string VEGAS_CLIENT_MAX_DESPOOL_TIME =
//        //             "Max Despool Time";
//        //         private const string VEGAS_CLIENT_MAX_DESPOOL_TIME_HELP =
//        //             "Maximum time to despool since the last session was opened";

//        //         public const string VEGAS_CLIENT_PACKET_READ_TIME =
//        //             "Packet Read Time";
//        //         private const string VEGAS_CLIENT_PACKET_READ_TIME_HELP =
//        //             "The average time for Vegas to read and decrypt a packet from the network.";

//        //         public const string VEGAS_CLIENT_PACKET_WRITE_TIME =
//        //             "Packet Write Time";
//        //         private const string VEGAS_CLIENT_PACKET_WRITE_TIME_HELP =
//        //             "The average time for Vegas to encrypt and write a packet to the network.";

//        public const string VEGAS_CLIENT_PACKET_SIZE =
//            "Average Packet Size";
//        private const string VEGAS_CLIENT_PACKET_SIZE_HELP =
//            "Average Packet Size";

//        public const string VEGAS_CLIENT_PACKETS_PER_SECOND =
//            "Packets Per Second";
//        private const string VEGAS_CLIENT_PACKETS_PER_SECOND_HELP =
//            "Packets per second";


//        public event BoundStateChangedHandler BoundStateChanged;

//        static Broker()
//        {
//            // Create Vegas client performance counters.

//            // Delete old category.
//            if (PerformanceCounterCategory.Exists(VEGAS_CLIENT_CATEGORY))
//                PerformanceCounterCategory.Delete(VEGAS_CLIENT_CATEGORY);

//            CounterCreationDataCollection counterDataCollection =
//                new CounterCreationDataCollection();

//            //             // Spool time counter.
//            //             CounterCreationData spoolTimeCounterData = new CounterCreationData(
//            //                 VEGAS_CLIENT_SPOOL_TIME,
//            //                 VEGAS_CLIENT_SPOOL_TIME_HELP,
//            //                 PerformanceCounterType.AverageCount64);
//            //             counterDataCollection.Add(spoolTimeCounterData);
//            //             CounterCreationData spoolTimeBaseData = new CounterCreationData(
//            //                 VEGAS_CLIENT_SPOOL_TIME + "Base",
//            //                 VEGAS_CLIENT_SPOOL_TIME_HELP,
//            //                 PerformanceCounterType.AverageBase);
//            //             counterDataCollection.Add(spoolTimeBaseData);

//            //             // Max spool time.
//            //             CounterCreationData maxSpoolTimeCounterData = new CounterCreationData(
//            //                 VEGAS_CLIENT_MAX_SPOOL_TIME,
//            //                 VEGAS_CLIENT_MAX_SPOOL_TIME_HELP,
//            //                 PerformanceCounterType.NumberOfItems32);
//            //             counterDataCollection.Add(maxSpoolTimeCounterData);

//            //             // Spool bytes written.
//            //             CounterCreationData spoolBytesWrittenData = new CounterCreationData(
//            //                 VEGAS_CLIENT_SPOOL_BYTES_WRITTEN,
//            //                 VEGAS_CLIENT_SPOOL_BYTES_WRITTEN_HELP,
//            //                 PerformanceCounterType.NumberOfItems32);
//            //             counterDataCollection.Add(spoolBytesWrittenData);

//            //             // Spool number of writes.
//            //             CounterCreationData spoolNumWritesData = new CounterCreationData(
//            //                 VEGAS_CLIENT_SPOOL_NUM_WRITES,
//            //                 VEGAS_CLIENT_SPOOL_NUM_WRITES_HELP,
//            //                 PerformanceCounterType.NumberOfItems32);
//            //             counterDataCollection.Add(spoolNumWritesData);

//            //             // Despool time counter.
//            //             CounterCreationData despoolTimeCounterData = new CounterCreationData(
//            //                 VEGAS_CLIENT_DESPOOL_TIME,
//            //                 VEGAS_CLIENT_DESPOOL_TIME_HELP,
//            //                 PerformanceCounterType.AverageCount64);
//            //             counterDataCollection.Add(despoolTimeCounterData);
//            //             CounterCreationData despoolTimeBaseData = new CounterCreationData(
//            //                 VEGAS_CLIENT_DESPOOL_TIME + "Base",
//            //                 VEGAS_CLIENT_DESPOOL_TIME_HELP,
//            //                 PerformanceCounterType.AverageBase);
//            //             counterDataCollection.Add(despoolTimeBaseData);

//            //             // Max despool time.
//            //             CounterCreationData maxDespoolTimeCounterData = new CounterCreationData(
//            //                 VEGAS_CLIENT_MAX_DESPOOL_TIME,
//            //                 VEGAS_CLIENT_MAX_DESPOOL_TIME_HELP,
//            //                 PerformanceCounterType.NumberOfItems32);
//            //             counterDataCollection.Add(maxDespoolTimeCounterData);

//            //             // Packet read time counter.
//            //             CounterCreationData packetReadTimeCounterData = new CounterCreationData(
//            //                 VEGAS_CLIENT_PACKET_READ_TIME,
//            //                 VEGAS_CLIENT_PACKET_READ_TIME_HELP,
//            //                 PerformanceCounterType.AverageCount64);
//            //             counterDataCollection.Add(packetReadTimeCounterData);
//            //             CounterCreationData packetReadTimeBaseData = new CounterCreationData(
//            //                 VEGAS_CLIENT_PACKET_READ_TIME + "Base",
//            //                 VEGAS_CLIENT_PACKET_READ_TIME_HELP,
//            //                 PerformanceCounterType.AverageBase);
//            //             counterDataCollection.Add(packetReadTimeBaseData);

//            //             // Packet write time counter.
//            //             CounterCreationData packetWriteTimeCounterData = new CounterCreationData(
//            //                 VEGAS_CLIENT_PACKET_WRITE_TIME,
//            //                 VEGAS_CLIENT_PACKET_WRITE_TIME_HELP,
//            //                 PerformanceCounterType.AverageCount64);
//            //             counterDataCollection.Add(packetWriteTimeCounterData);
//            //             CounterCreationData packetWriteTimeBaseData = new CounterCreationData(
//            //                 VEGAS_CLIENT_PACKET_WRITE_TIME + "Base",
//            //                 VEGAS_CLIENT_PACKET_WRITE_TIME_HELP,
//            //                 PerformanceCounterType.AverageBase);
//            //             counterDataCollection.Add(packetWriteTimeBaseData);

//            //             // Queue size.
//            //             CounterCreationData queueSize = new CounterCreationData(
//            //                 "Queue Size", "Queue size", PerformanceCounterType.NumberOfItems32);
//            //             counterDataCollection.Add(queueSize);

//            // Average packet size.
//            CounterCreationData packetSizeCounterData = new CounterCreationData(
//                VEGAS_CLIENT_PACKET_SIZE,
//                VEGAS_CLIENT_PACKET_SIZE_HELP,
//                PerformanceCounterType.AverageCount64);
//            counterDataCollection.Add(packetSizeCounterData);
//            CounterCreationData packetSizeBaseData = new CounterCreationData(
//                VEGAS_CLIENT_PACKET_SIZE + "Base",
//                VEGAS_CLIENT_PACKET_SIZE_HELP,
//                PerformanceCounterType.AverageBase);
//            counterDataCollection.Add(packetSizeBaseData);

//            // Packets per second.
//            CounterCreationData packetsPerSecondCounterData = new CounterCreationData(
//                VEGAS_CLIENT_PACKETS_PER_SECOND,
//                VEGAS_CLIENT_PACKETS_PER_SECOND_HELP,
//                PerformanceCounterType.RateOfCountsPerSecond32);
//            counterDataCollection.Add(packetsPerSecondCounterData);

//            // Create category and counters.
//            PerformanceCounterCategory.Create(
//                VEGAS_CLIENT_CATEGORY,
//                VEGAS_CLIENT_CATEGORY_HELP,
//                PerformanceCounterCategoryType.MultiInstance,
//                counterDataCollection);
//        }

//        public Broker(IBinder binder, string spoolDirectoryPath) :
//            this(binder, spoolDirectoryPath, DEFAULT_FORCE_REBIND_INTERVAL)
//        {
//        }

//        public Broker(IBinder binder, string spoolDirectoryPath, TimeSpan forceRebindInterval) :
//            this(binder, spoolDirectoryPath, forceRebindInterval, DEFAULT_READ_TIMEOUT)
//        {
//        }

//        public Broker(IBinder binder,
//                      string spoolDirectoryPath,
//                      TimeSpan forceRebindInterval,
//                      TimeSpan readTimeout)
//        {
//            m_binder = binder;
//            m_spoolDirectoryPath = spoolDirectoryPath;
//            m_forceRebindInterval = forceRebindInterval;
//            m_readTimeout = readTimeout;

//            // Create spool directory if it doesn't already exist.
//            Directory.CreateDirectory(spoolDirectoryPath);
//        }

//        public string SpoolDirectory
//        {
//            get { return m_spoolDirectoryPath; }
//        }

//        void OnBoundStateChanged(ServiceEndpoint binding)
//        {
//            Log.Verbose("Binding set to '{0}'", binding == null ? "none" : binding.ToString());
//            if (BoundStateChanged != null)
//            {
//                try
//                {
//                    BoundStateChanged(binding);
//                }
//                catch (Exception ex)
//                {
//                    Log.Verbose("Problem sending binding event: {0}", ex);
//                }
//            }
//        }

//        public bool IsBound
//        {
//            get
//            {
//                lock (m_vegasSessionMutex)
//                {
//                    return m_vegasSession != null;
//                }
//            }
//        }

//        public bool Connected
//        {
//            get
//            {
//                VegasSession vegasSession;
//                lock (m_vegasSessionMutex)
//                {
//                    if (m_vegasSession == null)
//                        return false;
//                    vegasSession = m_vegasSession;
//                }
//                vegasSession.Ping();
//                lock (m_vegasSessionMutex)
//                {
//                    return m_vegasSession != null;
//                }
//            }
//        }

//        internal DeSpooler DeSpooler
//        {
//            get { return m_despooler; }
//        }

//        public void Start()
//        {
//            m_bindingTimer = new Timer(Bind, null, 0, Timeout.Infinite);
//            m_rebindTimer = new Timer(Rebind);
//            ScheduleRebind();
//            m_despooler = new DeSpooler(this);
//            FindSpoolFiles();
//        }

//        void ScheduleRebind()
//        {
//            if (m_forceRebindInterval > TimeSpan.Zero)
//            {
//                // The actual rebind time is up to 50% more than specified in m_forceRebindInterval.
//                // This random addition makes it so that clients don't all attempt to rebind to a new
//                // vegas service at the same time.
//                double randomFactor = 1 + .5 * m_random.NextDouble();
//                TimeSpan actualRebindInterval = TimeSpan.FromMilliseconds((int)(m_forceRebindInterval.TotalMilliseconds * randomFactor));
//                Log.Verbose("Next check for rebind will be in {0}", actualRebindInterval);
//                m_rebindTimer.Change(actualRebindInterval, TimeSpan.FromMilliseconds(1).Negate());
//            }
//        }

//        public void Stop()
//        {
//            Log.Verbose("Stopping");
//            m_bindingTimer.Change(Timeout.Infinite, Timeout.Infinite);
//            m_despooler.Stop();
//            m_rebindLock.AcquireReaderLock(Timeout.Infinite);
//            try
//            {
//                if (IsBound)
//                {
//                    LockCookie lockCookie = m_rebindLock.UpgradeToWriterLock(Timeout.Infinite);
//                    try
//                    {
//                        lock (m_vegasSessionMutex)
//                        {
//                            m_vegasSession.Dispose();
//                            m_vegasSession = null;
//                            m_currentBinding = null;
//                        }
//                    }
//                    finally
//                    {
//                        m_rebindLock.DowngradeFromWriterLock(ref lockCookie);
//                    }
//                }
//            }
//            finally
//            {
//                m_rebindLock.ReleaseReaderLock();
//            }
//        }

//        public void SendApplicationMessage(byte[] argument)
//        {
//            m_rebindLock.AcquireReaderLock(Timeout.Infinite);
//            try
//            {
//                VegasSession vegasSession;
//                lock (m_vegasSessionMutex)
//                {
//                    if (m_vegasSession == null)
//                        throw new Exception("client not connected");
//                    vegasSession = m_vegasSession;
//                }
//                vegasSession.SendApplicationMessage(argument);
//            }
//            catch (Exception ex)
//            {
//                Log.Verbose("Unable to send application message: {0}", ex);
//                throw;
//            }
//            finally
//            {
//                m_rebindLock.ReleaseReaderLock();
//            }
//        }

//        void FindSpoolFiles()
//        {
//            string[] fileNames = Directory.GetFiles(m_spoolDirectoryPath);
//            foreach (string fileName in fileNames)
//            {
//                try
//                {
//                    new SpoolQueue(fileName, this);
//                }
//                catch (Exception ex)
//                {
//                    Log.Verbose("Unable to open spool file: {0}", fileName, ex);
//#if DEBUG
//                    Log.Verbose("Removing invalid queue file {0}", fileName);
//                    try
//                    {
//                        File.Delete(fileName);
//                    }
//                    catch (Exception ex2)
//                    {
//                        Log.Verbose("Unable to remove {0}", fileName, ex2);
//                    }
//#endif
//                }
//            }
//        }

//        public void RegisterCallback(Guid moduleGuid, DespoolNotificationDelegate del)
//        {
//            m_callbacks[moduleGuid] = del;
//        }

//        internal void Callback(Guid moduleGuid, byte[] arguments, byte[] message, MemoryReader reply, Exception ex)
//        {
//            // TBD: the exception should be passed back to delegate.
//            DespoolNotificationDelegate del = null;
//            if (m_callbacks.TryGetValue(moduleGuid, out del))
//                del(arguments, message, reply != null ? reply.GetRemainingBytes() : null);
//        }

//        public AsyncChannel OpenAsyncChannel(Guid moduleGuid, Guid sessionGuid, byte[] arguments)
//        {
//            return new AsyncChannel(this, m_spoolDirectoryPath, moduleGuid, sessionGuid, arguments);
//        }

//        public SyncChannel OpenSyncChannel(Guid moduleGuid, byte[] arguments)
//        {
//            m_rebindLock.AcquireReaderLock(Timeout.Infinite);
//            try
//            {
//                VegasSession vegasSession;
//                lock (m_vegasSessionMutex)
//                {
//                    if (m_vegasSession == null)
//                        throw new Exception("client not connected");
//                    vegasSession = m_vegasSession;
//                }
//                Channel channel = vegasSession.OpenChannel(new ChannelEndpoint(moduleGuid), arguments);
//                SyncChannel syncChannel = new SyncChannel(this, channel);
//                return syncChannel;
//            }
//            finally
//            {
//                m_rebindLock.ReleaseReaderLock();
//            }
//        }

//        void Rebind(object state)
//        {
//            m_rebindLock.AcquireReaderLock(Timeout.Infinite);
//            try
//            {
//                lock (m_vegasSessionMutex)
//                {
//                    if (m_vegasSession != null)
//                        m_forceRebind = true;
//                }
//                ScheduleRebind();
//            }
//            finally
//            {
//                m_rebindLock.ReleaseReaderLock();
//            }
//        }

//        void Bind(object state)
//        {
//            Log.Trace("Checking connection");
//            try
//            {
//                lock (m_bindInProgressMutex)
//                {
//                    if (m_bindInProgress)
//                    {
//                        Log.Trace("A Bind operation is already in progress.");
//                        return;
//                    }
//                    m_bindInProgress = true;
//                }

//                // Get updated list of servers.
//                IList<ServiceEndpoint> servers;
//                try
//                {
//                    servers = m_binder.GetServers();
//                }
//                catch (Exception ex)
//                {
//                    Log.Verbose("Unable to get list of servers: {0}", ex);
//                    servers = new List<ServiceEndpoint>(0);
//                }

//                m_rebindLock.AcquireReaderLock(Timeout.Infinite);
//                bool fireDisconnectedEvent = false;
//                IList<ServiceEndpoint> otherServers;
//                try
//                {
//                    // If we're currently connected...
//                    if (IsBound)
//                    {
//                        // Are we connected to a legit server?
//                        bool found = false;
//                        otherServers = new List<ServiceEndpoint>();
//                        foreach (ServiceEndpoint serviceEndpoint in servers)
//                        {
//                            if (m_currentBinding.HostAndSpnMatches(serviceEndpoint))
//                            {
//                                found = true;
//                            }
//                            else
//                            {
//                                otherServers.Add(serviceEndpoint);
//                            }
//                        }

//                        // If connected to a legit server...
//                        if (found)
//                        {
//                            // If not time for a forced rebind, we're done.
//                            if (!m_forceRebind)
//                                return;

//                            // We've been requested to rebind.
//                            m_forceRebind = false;
//                            Log.Trace("Checking to see whether we should rebind this connection");

//                            // If there are no other servers, don't attempt rebinding.
//                            if (otherServers.Count == 0)
//                            {
//                                Log.Trace("No other servers are configured.  No rebind possible");
//                                return;
//                            }
//                        }
//                        else
//                        {
//                            // The service we're connected to is no longer configured as a service.
//                            Log.Verbose("{0} is no longer configured as a service endpoint", m_currentBinding);

//                            // Close all Channels.
//                            LockCookie lockCookie = m_rebindLock.UpgradeToWriterLock(Timeout.Infinite);
//                            try
//                            {
//                                m_despooler.CloseChannels();
//                                lock (m_vegasSessionMutex)
//                                {
//                                    m_vegasSession.Dispose();
//                                    m_vegasSession = null;
//                                    m_currentBinding = null;
//                                }
//                                fireDisconnectedEvent = true;
//                            }
//                            finally
//                            {
//                                m_rebindLock.DowngradeFromWriterLock(ref lockCookie);
//                            }
//                        }
//                    }
//                    else
//                    {
//                        // We don't have a connection.
//                        Log.Trace("There is no connection to a server");
//                        otherServers = servers;
//                    }
//                }
//                finally
//                {
//                    m_rebindLock.ReleaseReaderLock();
//                }

//                // Fire off disconnected event if needed.
//                if (fireDisconnectedEvent)
//                    OnBoundStateChanged(null);

//                // Randomize the list of servers, and try to connect to one of them.
//                otherServers = RandomizeList(otherServers);
//                TryList(otherServers);
//            }
//            finally
//            {
//                // Reset the binding timer.
//                lock (m_bindInProgressMutex)
//                {
//                    m_bindingTimer.Change(BINDING_INTERVAL, Timeout.Infinite);
//                    m_bindInProgress = false;
//                }
//            }
//        }

//        // TBD: put this in some utility class.
//        IList<T> RandomizeList<T>(IList<T> list)
//        {
//            List<T> tempList = new List<T>(list);
//            List<T> newList = new List<T>();
//            while (tempList.Count > 0)
//            {
//                int index = m_random.Next(tempList.Count);
//                newList.Add(tempList[index]);
//                tempList.RemoveAt(index);
//            }
//            return newList;
//        }

//        // Attempt to connect to one of the specified service endpoints.
//        void TryList(IList<ServiceEndpoint> servers)
//        {
//            // For each endpoint...
//            foreach (ServiceEndpoint serviceEndpoint in servers)
//            {
//                try
//                {
//                    // Attempt to connect to the endpoint.
//                    Log.Trace("Attempting bind to {0}", serviceEndpoint);
//                    TcpClient tcpClient = new TcpClient();
//                    tcpClient.Connect(serviceEndpoint.Hostname, serviceEndpoint.Port);
//                    NetworkStream networkStream = tcpClient.GetStream();
//                    networkStream.ReadTimeout = (int)m_readTimeout.TotalMilliseconds;

//                    // Connection successful.  Authenticate to the server.
//                    SecureStream secureStream = new SecureStream(networkStream, false);
//                    secureStream.AuthenticateAsClient(serviceEndpoint.ServicePrincipalName,
//                                                      SecureStream.Options.Signed |
//                                                      SecureStream.Options.Sealed |
//                                                      SecureStream.Options.Symmetric);
//                    secureStream.WriteDataBlock(new byte[] { (byte)ProtocolVersion.Vegas1 });

//                    // Got new secured connection.  Now switch it in.
//                    m_rebindLock.AcquireWriterLock(Timeout.Infinite);
//                    try
//                    {
//                        // Close old channels and binding.
//                        Log.Trace("Closing old channels");
//                        m_despooler.CloseChannels();
//                        lock (m_vegasSessionMutex)
//                        {
//                            if (m_vegasSession != null)
//                            {
//                                Log.Trace("Closing old connection to {0}", m_currentBinding);
//                                m_vegasSession.Dispose();
//                                m_vegasSession = null;
//                                m_currentBinding = null;
//                            }
//                        }

//                        // Set new binding.
//                        VegasSession vegasSession = new VegasSession(secureStream);
//                        vegasSession.Disconnected += DisconnectedHandler;
//                        vegasSession.Start();
//                        vegasSession.SetRemoteType(RemoteType.Windows);
//                        lock (m_vegasSessionMutex)
//                        {
//                            m_vegasSession = vegasSession;
//                            m_currentBinding = serviceEndpoint;
//                        }
//                        Log.Trace("Bound to {0}", serviceEndpoint);
//                        m_despooler.WakeUp();
//                    }
//                    finally
//                    {
//                        m_rebindLock.ReleaseWriterLock();
//                    }
//                    OnBoundStateChanged(m_currentBinding);
//                    return;
//                }
//                catch (Exception ex)
//                {
//                    Log.Trace("Failed to connect to {0}: {1}", serviceEndpoint, ex);
//                }
//            }
//        }

//        void DisconnectedHandler(VegasSession vegasSession)
//        {
//            // Our VegasSession told us we're no longer connected.
//            lock (m_vegasSessionMutex)
//            {
//                if (m_vegasSession == vegasSession)
//                {
//                    Log.Verbose("VegasSession has disconnected");
//                    m_vegasSession = null;
//                    m_currentBinding = null;
//                }
//            }

//            // Let interested parties know about disconnect.
//            OnBoundStateChanged(null);
//        }
    }
}
